package nl.maarten.docenthelp.gui;

import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import nl.maarten.docenthelp.entity.Problem;
import nl.maarten.docenthelp.entity.Server;
import nl.maarten.docenthelp.entity.thread.AliveThread;
import nl.maarten.docenthelp.entity.thread.ConnectThread;
import nl.maarten.docenthelp.entity.thread.ListenThread;
import nl.maarten.docenthelp.manager.ProblemManager;

public class MainWindow extends JFrame implements WindowListener
{

	private static final long serialVersionUID = 8336586963786994967L;

	private static int[] WINDOW_SIZE = { 400, 400 };	
	
	private static final String WINDOW_TITLE = "Docent";
	
	private Server server;
	
	private ConnectThread connectThread;
	private AliveThread aliveThread;
	private ListenThread listenThread;
	
	private ProblemManager problemManager;
	
	private JScrollPane jspane;
	
	private DefaultTableModel dm;
	
	private JTable tblProblems;
	
	//huiswerk knoppen toevoegen!!!!!!!! anders spanky
	//TODO: knoppen toevoegen maarten
	
	public MainWindow()
	{
		init();
	}
	
	private void init()
	{
		setTitle(WINDOW_TITLE);		
		setLocationRelativeTo(null);
		setResizable(true); 
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(null);
		addComponentListener(new ComponentListener() 
		{
			
			@Override
			public void componentShown(ComponentEvent e)
			{
			}
			
			@Override
			public void componentResized(ComponentEvent e) 
			{
				WINDOW_SIZE[0] = getSize().width;
				WINDOW_SIZE[1] = getSize().height;
				resize();
			}
			
			@Override
			public void componentMoved(ComponentEvent e) 
			{
			}
			
			@Override
			public void componentHidden(ComponentEvent e) 
			{
			}
		});
		
		problemManager = ProblemManager.getInstance();
				
		dm = new DefaultTableModel();
		dm.addColumn("ID");
		dm.addColumn("Leerling");
		dm.addColumn("Categorie");
		dm.addColumn("Afgehandeld");
		
		tblProblems = new JTable()
		{

			private static final long serialVersionUID = 7960828301007314705L;

			@SuppressWarnings({ "unchecked", "rawtypes" })
			@Override
	         public Class getColumnClass(int column)
			 {
                switch (column) 
                {
                	case 0:
                		return Integer.class;
                    case 1:
                        return String.class;
                    case 2:
                        return String.class;
                    default:
                        return Boolean.class;
                }
            }
	    };
		tblProblems.setModel(dm);
		
		jspane = new JScrollPane(tblProblems);
		jspane.setLocation(0, 0);
		add(jspane);
		
		resize();

		//Making a server that listens to the port 1337
		server = new Server(1337, 7331);
		connectThread = new ConnectThread(server.getListenSocket(), server.getUdpSocket());
		connectThread.start();
		aliveThread = new AliveThread();
		aliveThread.start();
		listenThread = new ListenThread();
		listenThread.start();
		
		//Refreshing the problems
		//Refreshing the table after that
		//The timer will do this every 100 milliseconds, maybe make it slower? like every 1 second(1000 ms)
		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask()
		{
			@Override
			public void run() 
			{
				problemManager.refreshProblems();
				if(dm.getRowCount() > 0 )
				{
					for(int i = 0; i < dm.getRowCount(); ++i)
					{
						if((Boolean)dm.getValueAt(i, 3))
						{
							int id = (int)dm.getValueAt(i, 0);
							problemManager.problemCorrected(id);
						}
					}
					dm.setRowCount(0);
				}
				
				for(int i = 0; i < problemManager.getActiveProblems().size(); ++i)
				{
					Problem problem = problemManager.getActiveProblems().get(i);
					dm.addRow(new Object[]{problem.getID(), problem.getUser().getUsername(), problem.getCategory().getAbbreviation(),false});
				}
			}
		}, 100, 100);
		
		//TODO: remove maybe?
		/*
		for( Category cat : categoryManager.getCategories() )
		{
			System.out.println( "#" + cat.getId() + ": " + cat.getName() + "(" + cat.getAbbreviation() + ")");
		}
		
		for( Problem problem : problemManager.getProblems() )
		{
			System.out.println( problem.getUser().getUsername() + "(" + problem.getCategory().getAbbreviation() + ")");
		}
		*/
	}
	
	private void resize()
	{
		//Resize all the fields on the frame based on the current window size
		setSize(WINDOW_SIZE[0], WINDOW_SIZE[1]);
		setPreferredSize(new Dimension(WINDOW_SIZE[0], WINDOW_SIZE[1]));
		jspane.setSize(WINDOW_SIZE[0]-15,WINDOW_SIZE[1]-35);
		
		setVisible(true);
		pack();
	}

	@Override
	public void windowOpened(WindowEvent e) 
	{
	}

	@Override
	public void windowClosing(WindowEvent e)
	{
		if(connectThread != null)
		{
			connectThread.close();
		}
		
		if(aliveThread != null)
		{
			aliveThread.close();
		}
	}

	@Override
	public void windowClosed(WindowEvent e)
	{
	}

	@Override
	public void windowIconified(WindowEvent e)
	{
	}

	@Override
	public void windowDeiconified(WindowEvent e) 
	{
	}

	@Override
	public void windowActivated(WindowEvent e) 
	{
	}

	@Override
	public void windowDeactivated(WindowEvent e)
	{
	}
}
